"""
the creep class

need to make it so you can set any action to any other action? prob not, this stuff is gonna always be messy
so might as well do on a case by case basis (ie, if falling then use floater code if floater, if walking use 
runner code if a runner etc. )

should be able to check the animation state in this function, there should be variables that 
are set at different parts of the anim, such as halfway, done etc that can be made use of in here
this would limit the need for specialist code in the draw function

need a changeAnim function to do the same stuff the changeAction func does?

instead of canChangeAction have
self.allowedActions=["fall"," walker"]
so the object knows what actions it can change to on an anim by anim basis

Digging: a second animation should be created that basically deletes the background in time with the front anim?
would it be posible (and nice) to simply make the background dissapear behind the creep's anim?

*** If i put a pointer to like the game or something and have that have a pointer to the anims i can get away from passing in
the whole freaking anim & sounds thing


"""
from utility import *
import pygame

#creeps are the little dudes running around.  This class handles their movement and part of the animation
class creep_c:
    def __init__(self, startX = 0, startY = 0, startDir = 1, player=None, levelSurface = None, anims = None, game = None):
        #should grab the level pointer here so we can get all the rest of the creeps if req.
        
        self.x = startX
        self.y = startY
        #direction -1=left 1=right  - this should be passed in so the map can set from the entrance direction
        self.direction = startDir
        self.anims = anims
        self.anim = self.anims["fall_right"]
        
        self.game=game
        
        #controlling player
        self.player = player
        
        #current distance fallen

        self.fallDist=0
        
        #this should be somewhere else or something
        self.fallRate=2
        #0=falling 1=walking 2=down digging, 3 bomber, 4 confused, 5=builder, 6=exiting, climber=7,  floater=8, 9 blocker, 10 basher, 11 miner, 12 splut
        self.action=0
        #do this action when it's falling
        self.fallAction=0
        #set the image to "walk" on
        self.level = levelSurface
        #if this is true then actions can't be changed, until the current action releases them
        self.canChangeAction = True
        
        #frame number and delay till next frame
        self.frame = 0
        self.frameDelay = 0
        self.animEnded = False
        
        #delay till next movement of creep
        self.moveDelay = 0
        
        #used for stuff like builders who build exactly 13 loops etc
        self.animLoopCount = 0
        
        #this shouldn't happen probably, just delete?
        self.dead = False

    #user has requested change of action, test it's possible
    def reqChangeAction(self, newAction):
        if newAction==8:
            self.fallAction=8
            return True
        elif self.canChangeAction == True:
            self.changeAction(newAction)
            return True
        else:
            return False
    
    #change the creeps action to the requested action
    def changeAction(self, newAction):
        self.canChangeAction = True
        if newAction >= 0 and self.action != newAction:
        
            if self.action==9:
                self.game.remBlocker(self)
            if newAction==9:
                self.game.addBlocker(self)

            self.action=newAction
            self.frame=0
            self.animLoopCount=0
            
            #might have to reset fall distance only if changing to fall
            self.fallDist=0
            self.animEnded=False


    def move(self):
        if isOutsideBounds(self.x, self.y, self.level):
            self.dead=True

        #test if we have a floater and change it from faller if so
        if self.fallAction==8 and self.action==0:
            self.action=8
        
        #fall 0
        if self.action==0:
            height=0
            foundHeight=False
            
            self.canChangeAction=False
            
            #checks each pixel till it finds ground, steps up to full dist to fall if it's bigger than 1px
            while not foundHeight and height <= self.fallRate:
                if not isBlack(self.x, self.y + height, self.level):
                    foundHeight=True
                else:
                    height += 1
            
            self.y += height
            self.fallDist += height
            
            if self.direction==1:
                self.anim = self.anims["fall_right"]
            else:
                self.anim = self.anims["fall_left"]
            
            #change to walker if we're on the ground or splat if it's too far
            if foundHeight==True:
                if self.fallDist<=110:
                    self.changeAction(1)
                else:
                    self.changeAction(12)
        #floater 8
        elif self.action==8:
            height=0
            foundHeight=False
            
            self.canChangeAction=False
            
            #checks each pixel till it finds ground, steps up to full dist to fall if it's bigger than 1px
            while not foundHeight and height <= self.fallRate/2:
                if not isBlack(self.x, self.y + height, self.level):
                    foundHeight=True
                else:
                    height += 1
            
            self.y += height
            
            if self.anim!=self.anims["floater"] and self.anim!=self.anims["float_start"]:
                self.frame=0
                self.anim=self.anims["float_start"]
            
            #change to walker if we're on the ground
            if foundHeight==True:
                self.changeAction(1)
        
        #dig down 2
        elif self.action==2:
            self.anim=self.anims["dig_down"]
        #splut 12
        elif self.action==12:
            self.canChangeAction=False
            self.anim=self.anims["splut"]
        #explode em 3
        elif self.action==3:
            self.canChangeAction=False
            self.anim=self.anims["bomber"]
        #builder 5
        elif self.action==5:
            if isBlack(self.x, self.y-5,self.level) and isBlack(self.x+(6*self.direction), self.y-5,self.level):
                if self.direction==1:
                    self.anim=self.anims["builder_right"]
                else:
                    self.anim=self.anims["builder_left"]
            else:
                self.changeAction(1)
                self.direction*=-1
        #escaping 6
        elif self.action==6:
            self.canChangeAction = False
            self.anim = self.anims["exitAnim"]
        #miner 11
        elif self.action==11:
            if self.direction==1:
                self.anim = self.anims["miner_right"]
            else:
                self.anim = self.anims["miner_left"]
        #blocker 9
        elif self.action==9:
            self.canChangeAction=False
            self.anim = self.anims["blocker"]
            if isBlack(self.x, self.y+1, self.level):
                self.changeAction(self.fallAction)
        #walk 1
        elif self.action==1:
            if isBlack(self.x + self.direction, self.y, self.level):
                self.x += self.direction
                noGround = True
                height=0
                
                while height < 8 and noGround == True:
                    if not isBlack(self.x, self.y + height + 1, self.level):
                        noGround = False
                        self.y += height
                    height+=1
                    
                if noGround==True:
                    self.changeAction(self.fallAction)
            else:
                height=0
                foundHeight=False
                while height > -8 and not foundHeight:
                    if isBlack(self.x + self.direction, self.y + height, self.level) and not isBlack(self.x + self.direction, self.y + height + 1, self.level) :
                        foundHeight=True
                        self.y += height
                        self.x += self.direction

                    height-=1
                if foundHeight==False:
                    self.direction *= -1

            if self.direction==1:
                self.anim = self.anims["walk_right"]
            else:
                self.anim = self.anims["walk_left"]
        #confused 4
        #elif self.action==4:
        else:
            if self.animEnded:
                self.changeAction(1)
            else:
                if self.direction==1:
                    self.anim = self.anims["confused_right"]
                else:
                    self.anim = self.anims["confused_left"]

        for blocker in self.game.blockers:
            #check it's within 10px of y, might want to make this -10 to +2?
            if blocker.y > self.y-10 and blocker.y < self.y+10:
                if self.direction == 1:
                    if blocker.x < self.x + 10 and blocker.x > self.x + 8:
                        self.direction *= -1
                else:
                    if blocker.x > self.x - 10 and blocker.x<self.x - 8:
                        self.direction *= -1
        

    def draw(self, offset):
        #draw
        self.frame, self.animEnded, self.frameDelay = self.anim.draw(self.x-offset[0], self.y-offset[1], self.frame, True, False, self.frameDelay)
        #print self.frameDelay
        if self.animEnded:
            #explode?  or should we just set the action to the explode one?
            if self.action==3:
                #todo: make this use config.spriteSize[x] so i can make bigger sprites in future
                pygame.draw.circle(self.level, (0, 0, 0, 255), (self.x, self.y-8), 24)
                self.game.redrawArea += [(self.x-32, self.y-40, 64, 80)]
                self.dead = True
                #for i in range(3):
                #    config.objects += [obj_c(self.x, self.y, random.random()*20-10, -5, chunk1)]
                #need a sound library or something here
                self.game.playSound("pop")
                self.game.screen.blit(self.game.img["explosion"], (self.x-32, self.y-40))
            #confused
            elif self.action==4:
                self.changeAction(1)
            #builder
            elif self.action==5:
                self.animLoopCount+=1
                
                if self.animLoopCount==13:
                    self.changeAction(4)
                
                if self.direction==-1:
                    self.level.fill((247,214,214), (self.x-9, self.y-1, 12, 2))
                    self.x-=4
                    self.y-=2
                else:
                    self.level.fill((247,214,214), (self.x-1, self.y-1, 12, 2))
                    self.x+=4
                    self.y-=2
            #exit and splat, not sure if they should die by exiting.
            elif self.action==6 or self.action == 12:
                self.dead=True
            
            #finished confused anim, set up this way because different actions use the confused anim
            elif self.anim == self.anims["confused_right"] or self.anim == self.anims["confused_left"]:
                self.changeAction(1)
            
            #do the "pul out a brella" move then float normal
            elif self.anim == self.anims["float_start"] and self.action==8:
                self.anim = self.anims["floater"]
        #extra builder code
        if self.action==2 and self.frameDelay==0 and (self.frame==15 or self.frame==8):
            self.y+=2
            self.level.fill((0,0,0), (self.x - self.game.spriteSize[0]/4, self.y-4, self.game.spriteSize[0]/2, 4))
            if isBlack(self.x-4, self.y, self.level) and isBlack(self.x+4, self.y, self.level) and isBlack(self.x-4, self.y+2, self.level) and isBlack(self.x+4, self.y+2, self.level):
                self.changeAction(self.fallAction)
